<template>
  <edit-card :title="'在线部署'" :confirm-text="'确定'" :type="'add'" :loading="subLoading" @confirm="submit">
    <a-anchor
      style="position: absolute; top: 16px; right: 16px; width: 112px"
      :items="[
        { key: '1', href: '#components-anchor-demo-basic', title: '服务详情' },
        { key: '2', href: '#components-anchor-demo-static', title: '资源分配' }
      ]"
      wrapper-class="a-anchor-class"
      :target-offset="500"
      :offset-top="80 + 54"
      @click.prevent
    />
    <div id="components-anchor-demo-basic" class="default-class-title">服务详情</div>
    <a-form
      ref="mainFormRef"
      :colon="false"
      :model="mainForm"
      style="width: 824px"
      :rules="mainFormRules"
      name="mainForm"
      :label-align="'left'"
    >
      <a-form-item label="服务名称" name="name">
        <g-input v-model:value="mainForm.name" v-trim :search="false" class="w-440" placeholder="请输入服务名称" :maxlength="200" />
      </a-form-item>
      <a-form-item label="服务类型" name="serviceType">
        <a-radio-group v-model:value="mainForm.serviceType">
          <a-radio :value="0">HTTP</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item label="请求方式" name="requestMode">
        <a-select v-model:value="mainForm.requestMode" :options="requestTypeOptions" class="w-440" placeholder="请选择请求方式" />
      </a-form-item>
      <a-form-item label="输入参数" name="inParam">
        <a-space v-for="(param, index) in mainForm.inParam" :key="index" class="w-440" style="display: flex; gap: 12px" align="baseline">
          <a-form-item
            class="w-215"
            :name="['inParam', index, 'name']"
            :rules="{
              required: true,
              message: '请输入参数'
            }"
          >
            <a-input v-model:value="param.name" v-trim placeholder="请输入参数" />
          </a-form-item>
          <a-form-item
            class="w-215"
            :name="['inParam', index, 'value']"
            :rules="{
              required: true,
              message: '请输入值'
            }"
          >
            <a-input v-model:value="param.value" v-trim placeholder="请输入值" />
          </a-form-item>
          <MinusCircleOutlined v-if="param.canDelete" style="color: #cccdcf" title="删除" @click="removeParamInput(1, index)" />
        </a-space>
        <div class="w-440">
          <a-button type="dashed" block @click="addParam(1)">
            <PlusOutlined />
            <span style="color: rgba(17, 22, 31, 0.75)">添加</span>
          </a-button>
        </div>
      </a-form-item>
      <a-form-item label="输出参数" name="outParam">
        <a-space v-for="(param, index) in mainForm.outParam" :key="index" class="w-440" style="display: flex; gap: 12px" align="baseline">
          <a-form-item
            class="w-215"
            :name="['outParam', index, 'name']"
            :rules="{
              required: true,
              message: '请输入参数'
            }"
          >
            <a-input v-model:value="param.name" v-trim placeholder="请输入参数" />
          </a-form-item>
          <a-form-item
            class="w-215"
            :name="['outParam', index, 'value']"
            :rules="{
              required: true,
              message: '请输入值'
            }"
          >
            <a-input v-model:value="param.value" v-trim placeholder="请输入值" />
          </a-form-item>
          <MinusCircleOutlined v-if="param.canDelete" style="color: #cccdcf" title="删除" @click="removeParamInput(2, index)" />
        </a-space>
        <div class="w-440">
          <a-button type="dashed" block @click="addParam(2)">
            <PlusOutlined />
            <span style="color: rgba(17, 22, 31, 0.75)">添加</span>
          </a-button>
        </div>
      </a-form-item>
      <a-form-item label="描述" name="remark">
        <a-textarea v-model:value="mainForm.remark" v-trim class="w-440" placeholder="请输入描述" :maxlength="200" show-count />
      </a-form-item>
    </a-form>

    <div id="components-anchor-demo-static" class="default-class-title mt-120">资源分配</div>
    <a-form ref="resourceRef" :model="resourceForm" :colon="false" :rules="resourceRules" name="resourceForm" :label-align="'left'">
      <a-form-item label="GPU" name="gpu">
        <a-select v-model:value="resourceForm.gpu" :options="GPU_OPTIONS" class="w-440" />
      </a-form-item>
      <a-form-item label="CPU" name="cpuMemory">
        <a-select v-model:value="resourceForm.cpuMemory" :options="CPU_OPTIONS" class="w-440" @change="cpuMemoryChange" />
      </a-form-item>
    </a-form>
  </edit-card>
</template>

<script lang="ts" setup>
  import { message } from 'ant-design-vue'
  import type { Rule } from 'ant-design-vue/es/form'
  import { SelectValue } from 'ant-design-vue/es/select'
  import { cloneDeep } from 'g6-fn'
  import { ref } from 'vue'
  import { useRequest } from 'vue-request'
  import { useRouter } from 'vue-router'

  import { algoDevApi } from '@/services/api'
  import { validateBitLen, validateDirName } from '@/utils'

  import { CPU_OPTIONS, GPU_OPTIONS } from '../../algo-dev/options'

  const router = useRouter()

  const requestTypeOptions = [
    { label: 'get', value: 0 },
    { label: 'post', value: 1 }
  ]

  /** 详情 -------------------------------------------------------------------------------- */
  interface AddInputType {
    name: string
    value: any
    canDelete: boolean
  }
  interface MainForm {
    name: string
    serviceType: number | undefined
    requestMode: number | undefined
    inParam: AddInputType[]
    outParam: AddInputType[]
    remark: string
  }
  let mainFormRef = ref()
  let mainForm = ref<MainForm>({
    name: '',
    serviceType: 0,
    requestMode: undefined,
    inParam: [{ name: '', value: '', canDelete: false }],
    outParam: [{ name: '', value: '', canDelete: false }],
    remark: ''
  })

  const mainFormRules: Record<string, Rule[]> = {
    name: [
      { required: true, trigger: 'change', message: '请输入名称' },
      { validator: validateDirName() },
      { validator: validateBitLen(200), trigger: 'change' }
    ],
    serviceType: [{ required: true, message: '请选择服务类型' }],
    requestMode: [{ required: true, message: '请选择请求方式' }],
    inParam: [{ required: true, message: '请输入输入参数' }],
    outParam: [{ required: true, message: '请输入输出参数' }]
  }

  /* 资源分配逻辑 -------------------------------------------------------------------------- */
  let resourceRef = ref()
  let resourceForm = ref({
    gpu: 0,
    cpuMemory: '1-2',
    cpu: 1,
    memory: 2
  })

  const resourceRules: Record<string, Rule[]> = {
    gpu: [{ required: true, message: '请选择GPU' }],
    cpuMemory: [{ required: true, message: '请选择CPU' }]
  }
  const cpuMemoryChange = (val: string | SelectValue) => {
    if (typeof val === 'string' && val.includes('-')) {
      resourceForm.value.cpu = Number(val.split('-')[0])
      resourceForm.value.memory = Number(val.split('-')[1])
    }
  }

  /* 输入/输出参数---------------------------------------------------------------------------------------- */
  /**
   * 增加运行参数
   */
  const addParam = (type: 1 | 2) => {
    if (type === 1) {
      mainForm.value.inParam.push({
        name: '',
        value: '',
        canDelete: true
      })
      return
    }
    mainForm.value.outParam.push({
      name: '',
      value: '',
      canDelete: true
    })
  }
  /**
   * 删除运行参数
   */
  const removeParamInput = (type: 1 | 2, index: number) => {
    if (type === 1) {
      mainForm.value.inParam.splice(index, 1)
      return
    }
    mainForm.value.outParam.splice(index, 1)
  }

  /* 表单提交 -------------------------------------------------------------------------- */
  const formatParams = () => {
    let mainFormData = cloneDeep(mainForm.value)
    delete mainFormData.frame
    let resourceFormData = cloneDeep(resourceForm.value)
    delete resourceFormData.cpuMemory
    let paramData = { ...mainFormData, ...resourceFormData }
    console.log('提交的数据', paramData)
    return paramData
  }
  const { loading: subLoading, runAsync: addTraining } = useRequest<ResponseData<void>>(algoDevApi.addNotebook)
  const submit = async () => {
    await mainFormRef.value?.validate()
    await resourceRef.value?.validate()
    await addTraining(formatParams(), { isAddUid: true })
    message.success('创建成功')
    router.back()
  }
</script>

<style lang="less" scoped>
  .w-440 {
    width: 440px;
  }

  :deep(.ant-form-item) {
    margin-bottom: 40px;

    .ant-form-item-label > label {
      width: 120px;
    }
  }

  .default-class-title {
    .font20b();

    position: relative;
    margin-bottom: 50px;

    &::before {
      position: absolute;
      top: 50%;
      left: -16px;
      width: 3px;
      height: 22px;
      background: #1868e9;
      border-radius: 0 2px 2px 0;
      content: '';
      transform: translateY(-50%);
      flex: none;
      order: 0;
      align-self: stretch;
      flex-grow: 0;
    }
  }

  .a-anchor-class {
    position: absolute !important;
    top: 54px;
    right: 10;
  }
</style>
